#include "wx/dc.h"
#include "WorkFieldPanel.h"

WorkFieldPanel::WorkFieldPanel(
	wxWindow *parent,
	wxWindowID winid,
	const wxPoint& pos,
	const wxSize& size,
	long style,
	const wxString& name) :
wxPanel(parent, winid, pos, size, style, name)
{
	Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler( WorkFieldPanel::OnLmbDown ));
	Connect( wxEVT_LEFT_UP, wxMouseEventHandler( WorkFieldPanel::OnLmbUp ));
	Connect( wxEVT_MOTION, wxMouseEventHandler( WorkFieldPanel::OnMouseMove ));
	Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( WorkFieldPanel::OnMouseWheel ));
	Connect( wxEVT_PAINT, wxPaintEventHandler( WorkFieldPanel::OnPaint ));
	Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler( WorkFieldPanel::OnRmbDown ));
	Connect( wxEVT_RIGHT_UP, wxMouseEventHandler( WorkFieldPanel::OnRmbUp ));
	Connect( wxEVT_SIZE, wxSizeEventHandler( WorkFieldPanel::OnSize ));

    _renderer.Resize(size.GetWidth(), size.GetHeight());
    Transform camera( Vec2::ZERO, 0.0f, 5.0f );
    _renderer.SetCamera(camera);

    _document = 0;
}

WorkFieldPanel::~WorkFieldPanel()
{
	//dtor
}

void WorkFieldPanel::OnPaint( wxPaintEvent& event )
{
	wxPaintDC dc(this);
	Repaint(dc);
}

void WorkFieldPanel::Repaint(wxPaintDC& dc)
{
	PaintGrid(dc);

	if(_document == 0) return;

	wxPen pen(wxColor(0,0,0));
    pen.SetCap(wxCAP_PROJECTING);
    dc.SetPen(pen);

    dc.SetBrush(*wxTRANSPARENT_BRUSH);

    _document->Draw(_renderer, dc);
}

void WorkFieldPanel::PaintGrid(wxPaintDC& dc)
{
	float gridSize = 10.0f;
	for(float y = -gridSize; y <= gridSize; y += 1.0f)
		_renderer.DrawLine(dc, Vec2(-gridSize, y), Vec2(gridSize, y), wxColor(200, 200, 200));

	for(float x = -gridSize; x <= gridSize; x += 1.0f)
		_renderer.DrawLine(dc, Vec2(x, -gridSize), Vec2(x, gridSize), wxColor(200, 200, 200));

	_renderer.DrawLine(dc, Vec2(0.0f, -gridSize), Vec2(0.0f, gridSize), wxColor(0, 0, 0));
	_renderer.DrawLine(dc, Vec2(-gridSize, 0.0f), Vec2(gridSize, 0.0f), wxColor(0, 0, 0));
}

void WorkFieldPanel::OnSize( wxSizeEvent& event )
{
	wxSize size = event.GetSize();
    _renderer.Resize(size.GetWidth(), size.GetHeight());
    Refresh();
}

void WorkFieldPanel::OnLmbDown( wxMouseEvent& event )
{

}

void WorkFieldPanel::OnLmbUp( wxMouseEvent& event )
{

}

void WorkFieldPanel::OnRmbDown( wxMouseEvent& event )
{
	_screenMousePrev = event.GetPosition();
}

void WorkFieldPanel::OnRmbUp( wxMouseEvent& event )
{

}

void WorkFieldPanel::OnMouseMove( wxMouseEvent& event )
{
	if (!event.ButtonIsDown(wxMouseButton::wxMOUSE_BTN_RIGHT)) return;

	wxPoint screenMouseCurrent = event.GetPosition();

	Vec2 worldMousePrev = _renderer.GetWorldCoords(_screenMousePrev);
	Vec2 worldMouseCurrent = _renderer.GetWorldCoords(screenMouseCurrent);
	Vec2 worldDelta = worldMouseCurrent - worldMousePrev;

//	wxString str;
//	str.Printf(
//		wxT("screenPrev X=%2d Y=%2d; screenCurrent X=%2d Y=%2d; worldDelta X=%2.2f Y=%2.2f;"),
//		_screenMousePrev.x, _screenMousePrev.y, screenMouseCurrent.x, screenMouseCurrent.y, worldDelta.X, worldDelta.Y);
//	wxPuts(str);


	Transform camera = _renderer.GetCamera();
	camera.Vec -= worldDelta;
	_renderer.SetCamera( camera );
	_screenMousePrev = screenMouseCurrent;

	Refresh();
}

void WorkFieldPanel::OnMouseWheel( wxMouseEvent& event )
{
	const float SCALE_DELTA = 1.05f;
	float wheelRot = -float(event.GetWheelRotation() / 120);

	Transform camera = _renderer.GetCamera();
	camera.Scale *= pow(SCALE_DELTA, wheelRot);
	_renderer.SetCamera( camera );
	Refresh();
}
